import axios from 'axios'
import type {
    AxiosInstance,
    InternalAxiosRequestConfig,
    AxiosRequestConfig,
    AxiosResponse,
    AxiosError,
} from 'axios'
import { ElMessage } from 'element-plus'
import { config } from '@/config'
import useStore from '@/store'
import router from '@/router'

const service: AxiosInstance = axios.create({
    baseURL: '/api',
    timeout: config.reqTimeout,
    headers: { 'Content-Type': 'application/json' },
})

// 请求拦截
// TODO AxiosRequestConfig 提示错误
service.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
        const { user } = useStore()
        const { useToken } = user
        if(useToken) {
            config.headers.Authorization = 'Bearer ' + useToken
        }
        // get请求防止缓存
        // if(config.method === 'get' || config.method === 'GET') {
        //     config.params.valueOf = Date.now()
        // }
        if (config.data) {
        }
        return config
    },
    (error: AxiosError) => {
        ElMessage.error(error.message)
        return Promise.reject(error)
    },
)

// 自定义返回的类型传递给AxiosError
// 详见 AxiosResponse T参数
interface ResponseData {
    message: string
    status: number
    success: boolean
}


// 响应拦截
service.interceptors.response.use(
    (response: AxiosResponse) => {
        const { code, message, data } = response.data
        if (code === 200) {
            return response.data
        } else {
            ElMessage.error(message)
            return Promise.reject(new Error(message))
        }
    },
    (error: AxiosError<ResponseData>) => {
        const status = error.response?.status
        let message = error.response?.data.message
        switch (status) {
            case 401:
                message = message || 'token失效'
                router.push({ path: '/sign-in' })
                break
            case 403:
                message = message || '拒绝访问'
                break
            case 404:
                message = message || '请求地址错误'
                break
            case 500:
                message = message || '服务器故障'
                break
            default:
                message = message || '未知错误'
        }
        ElMessage.error(message)
        return Promise.reject(error.response?.data || error.response)
    },
)

export function get<T = any>(
    url: string,
    config?: AxiosRequestConfig
): Promise<T> {
    return service.get(url, config)
}

export function post<T = any>(
    url: string,
    data?: object,
    config?: AxiosRequestConfig,
): Promise<T> {
    return service.post(url, data, config)
}
